//
//  ZZCURLQueryParser.swift
//  ewgShop
//
//  Created by zzc on 2019/8/5.
//  Copyright © 2019 zzc. All rights reserved.
//

import UIKit
import Foundation

class ZZCURLQueryParser: NSObject {

    typealias argumentHandler = (_ path : String) -> ();
    var argumentHandlers = NSMutableDictionary.init();
    var argumentNonexistentHandlers = NSMutableDictionary.init();
    
    /// 注册特定URL参数handle
    ///
    /// - Parameters:
    ///   - argument: <#argument description#>
    ///   - handler: <#handler description#>
    func registerQueryArgumentWithHandler(argument : String? , handler : argumentHandler?){
        if argument == nil {
            return;
        }
        
        let argumentsTemp = (argument?.components(separatedBy: ","))! as [String];
        if handler == nil {
            (argumentsTemp as NSArray).enumerateObjects { (obj, idx, stop) in
                self.argumentHandlers.removeObject(forKey: (obj as! NSString).lowercased)
            }
        }else{
            (argumentsTemp as NSArray).enumerateObjects { (obj, idx, stop) in
                self.argumentHandlers.setObject(handler!, forKey: (obj as! NSString).lowercased as NSCopying)
            }
        }
    }
    
    /// 注册不存在特定URL参数时handle
    ///
    /// - Parameters:
    ///   - argument: <#argument description#>
    ///   - handler: <#handler description#>
    func registerQueryArgumentWithNonexistentHandler(argument : String?,handler : argumentHandler? ){
        if argument == nil {
            return;
        }
        let argumentsTemp = (argument?.components(separatedBy: ","))! as [String];
        if handler == nil {
            (argumentsTemp as NSArray).enumerateObjects { (obj, idx, stop) in
                self.argumentNonexistentHandlers.removeObject(forKey: (obj as! NSString).lowercased)
            }
        }else{
            (argumentsTemp as NSArray).enumerateObjects { (obj, idx, stop) in
                self.argumentNonexistentHandlers.setObject(handler!, forKey: (obj as! NSString).lowercased as NSCopying)
            }
        }
    }
    
    
    /// 处理URL
    ///
    /// - Parameter url: <#url description#>
    func handleURL(url : NSURL?) {
        if url == nil {
            return
        }
        
        let argumentsString = argumentsOfURL(url: url)
        print("argumentsString :\(argumentsString)")
        
        if argumentsString.length > 0 {
            
            let arguments = argumentsString.components(separatedBy: ",")
            for (_ , obj) in arguments.enumerated(){
                
                let handle : argumentHandler? = self.argumentHandlers.object(forKey: obj.lowercased()) as? ZZCURLQueryParser.argumentHandler;
                if handle != nil {
                    handle!(obj.lowercased())
                }
            }
        }else{
            self.argumentHandlers.enumerateKeysAndObjects { (key, obj, stop) in
                
                if ( (url!.absoluteString! as NSString).range(of: key as! String, options: NSString.CompareOptions.caseInsensitive)).length > 0{
                    (obj as! argumentHandler)(key as! String);
                }
            }
        }
        
        if self.argumentNonexistentHandlers.count > 0 {
            self.argumentNonexistentHandlers.enumerateKeysAndObjects { (key, obj, stop) in
                if ( (url!.absoluteString! as NSString).range(of: key as! String, options: NSString.CompareOptions.caseInsensitive)).length == 0{
                    (obj as! argumentHandler)(key as! String);
                }
            }
        }
        
    }
    
    
    /// 提取URL参数
    ///
    /// - Parameter url: <#url description#>
    /// - Returns: <#return value description#>
    private func argumentsOfURL(url : NSURL?)-> NSString{
        
        if url?.absoluteString?.lowercased().lengthOfBytes(using: String.Encoding.utf8) ?? 0 <= 0 {
            return ""
        }
        
        var argumentsString = NSString.init()
        
        let urlComponents = NSURLComponents.init(string: (url?.absoluteString)!);
    
        if(urlComponents?.query != nil && (urlComponents!.query! as NSString).range(of: "ZZCAppArg", options: NSString.CompareOptions.caseInsensitive).length > 0){
            
            (urlComponents!.queryItems! as NSArray).enumerateObjects { (obj, idx, stop) in
                if (((obj as! URLQueryItem).name as NSString).range(of: "ZZCAppArg", options: NSString.CompareOptions.caseInsensitive).length > 0 ){
                    argumentsString = (obj as! URLQueryItem).value! as NSString
                }
            }
        }else if url?.fragment != nil && (((url!).fragment! as NSString).range(of: "ZZCAppArg", options: NSString.CompareOptions.caseInsensitive)).length > 0 {
            let fragementURL = NSURL.init(string: NSString.init(format: "?%@", (url?.fragment)!) as String)
            
            let fragmentURLComponents = NSURLComponents.init(url: fragementURL! as URL, resolvingAgainstBaseURL: false)
            
            for (index , obj) in (fragmentURLComponents!.queryItems! as NSArray).enumerated(){
                print("enum idx:\(index)")
                if (((obj as! URLQueryItem).name as NSString).range(of: "ZZCAppArg", options: NSString.CompareOptions.caseInsensitive).length > 0) {
                    argumentsString = (obj as! URLQueryItem).value! as NSString;
                    break;
                }
            }
        }
        
        if argumentsString.length == 0 && urlComponents?.queryItems != nil{
            
            for (idx , obj) in (urlComponents!.queryItems! as NSArray).enumerated(){
                var queryItem = obj as! URLQueryItem
                print("enum index : \(idx)")
                if ((queryItem.name as NSString).range(of: "ZZCAppArg", options: NSString.CompareOptions.caseInsensitive).length > 0) {
                    let queryURL = NSURL.init(string: queryItem.value!)
                    argumentsString = self.argumentsOfURL(url: queryURL);
                    break;
                }
            }
        }
        return argumentsString;
    }
    
    func queryOfRequestURLHasArgument(requestURL:NSURL,argument:String) -> Bool {
        var hasArgument = false
        let arguments = argumentsOfURL(url: requestURL);
        
        if arguments.range(of: argument, options: NSString.CompareOptions.caseInsensitive).length > 0 {
            hasArgument = true
        }
        return hasArgument;
    }
    
    
}
